package com.ruoyi.system.utils;


import io.minio.MinioClient;
import io.minio.SetBucketPolicyArgs;
import io.minio.errors.MinioException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
 * MinIO 桶权限控制工具类
 */
public class MinioBucketPermissionUtil {

    // MinIO 连接配置（替换为你的实际配置）
    private static final String MINIO_ENDPOINT = "http://119.29.117.29:9000"; // API 地址（9000端口）
    private static final String ACCESS_KEY = "minioadmin"; // 管理员账号
    private static final String SECRET_KEY = "minio@123456"; // 管理员密码

    // 初始化 MinIO 客户端
    private static MinioClient getMinioClient() {
        return MinioClient.builder()
                .endpoint(MINIO_ENDPOINT)
                .credentials(ACCESS_KEY, SECRET_KEY)
                .build();
    }

    /**
     * 设置桶为「公开访问」（允许任何人读取桶内文件）
     * 规则：允许所有用户（*）对桶内所有文件（/*）执行读取操作（s3:GetObject）
     * @param bucketName 桶名（如 "nalang"）
     */
    public static void setBucketPublic(String bucketName) throws Exception {
        MinioClient client = getMinioClient();

        // 定义公开访问的 Policy JSON（MinIO 基于 AWS S3 Policy 语法）
        String publicPolicy = "{\n" +
                "  \"Version\": \"2012-10-17\",\n" +
                "  \"Statement\": [\n" +
                "    {\n" +
                "      \"Effect\": \"Allow\",\n" +
                "      \"Principal\": \"*\",\n" + // 所有用户
                "      \"Action\": \"s3:GetObject\",\n" + // 允许读取文件
                "      \"Resource\": \"arn:aws:s3:::" + bucketName + "/*\"\n" + // 桶内所有文件
                "    }\n" +
                "  ]\n" +
                "}";

        // 应用 Policy 到桶
        client.setBucketPolicy(SetBucketPolicyArgs.builder()
                .bucket(bucketName)
                .config(publicPolicy)
                .build());

        System.out.println("桶 " + bucketName + " 已设置为公开访问");
    }

    /**
     * 设置桶为「私有访问」（仅管理员和授权用户可访问）
     * @param bucketName 桶名
     */
    public static void setBucketPrivate(String bucketName) throws Exception {
        MinioClient client = getMinioClient();

        // 清空 Policy（私有访问即无公开规则）
        client.setBucketPolicy(SetBucketPolicyArgs.builder()
                .bucket(bucketName)
                .config("") // 空字符串表示移除所有公开规则
                .build());

        System.out.println("桶 " + bucketName + " 已设置为私有访问");
    }

    /**
     * 自定义桶权限（例如：仅允许指定 IP 访问）
     * @param bucketName 桶名
     * @param allowedIp 允许访问的 IP（如 "192.168.1.100"）
     */
    public static void setCustomPolicy(String bucketName, String allowedIp) throws Exception {
        MinioClient client = getMinioClient();

        // 自定义 Policy：仅允许指定 IP 读取文件
        String customPolicy = "{\n" +
                "  \"Version\": \"2012-10-17\",\n" +
                "  \"Statement\": [\n" +
                "    {\n" +
                "      \"Effect\": \"Allow\",\n" +
                "      \"Principal\": \"*\",\n" +
                "      \"Action\": \"s3:GetObject\",\n" +
                "      \"Resource\": \"arn:aws:s3:::" + bucketName + "/*\",\n" +
                "      \"Condition\": {\n" +
                "        \"IpAddress\": {\n" +
                "          \"aws:SourceIp\": \"" + allowedIp + "/32\"\n" + // 仅允许该 IP
                "        }\n" +
                "      }\n" +
                "    }\n" +
                "  ]\n" +
                "}";

        client.setBucketPolicy(SetBucketPolicyArgs.builder()
                .bucket(bucketName)
                .config(customPolicy)
                .build());

        System.out.println("桶 " + bucketName + " 已设置自定义权限（仅允许 IP：" + allowedIp + "）");
    }

    // 测试方法
    public static void main(String[] args) {
        String bucketName = "nalang"; // 你的桶名
        try {
            // 示例1：设置为公开访问（解决 AccessDenied 问题）
            setBucketPublic(bucketName);

            // 示例2：设置为私有访问（如需关闭公开）
            // setBucketPrivate(bucketName);

            // 示例3：设置自定义权限（仅允许指定 IP）
            // setCustomPolicy(bucketName, "192.168.1.100");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}